// Gomoku.cpp : Defines the entry point for the console application.

#include "Include.h"
#include "GomokuPlayer.h"
#include "LocalPlayer.h"
#include "SearchPlayer.h"
#include "ThreatSpacePlayer.h"
#include "Threat.h"

bool CheckForWin(Board& _board, int _player);
void PrintBoard(Board& _board);

int main()
{
	Init();
	srand(time(NULL));

	Board t_gameBoard;
	GomokuPlayer *t_player1 = new LocalPlayer();
	GomokuPlayer *t_player2 = new ThreatSpacePlayer();
	int t_spectatorListener = tcplisten(14800, 8, 1);
	std::vector<int> t_spectators;
	
	//LoadThreatReference("threatRef.txt");

	// Reset Board
	for(int a = 0; a < 19; a++)
	{
		for(int b = 0; b < 19; b++)
		{
			t_gameBoard[a][b] = 0;
		}
	}

	int t_turn = 1;
	while(true)
	{
		PrintBoard(t_gameBoard);
		
		Move t_move;

		// Get Move base on current turn
		UINT t_start = GetTickCount();
		if(t_turn == 1)
		{
			t_player1->Play(t_turn, t_gameBoard, t_move);
		}
		else
		{
			t_player2->Play(t_turn, t_gameBoard, t_move);
		}

		std::cout << "\nMove took " << (float) ((GetTickCount() - t_start) / 1000) << " seconds\n";

		// Check Move is Valid
		if(t_gameBoard[t_move[0]][t_move[1]] == 0)
		{
			t_gameBoard[t_move[0]][t_move[1]] = t_turn;
		}

		// Check for new spectators
		int t_newSpectator = tcpaccept(t_spectatorListener, 1);
		while(t_newSpectator > 0)
		{
			std::cout << "New Spectator has Connected\n";
			t_spectators.push_back(t_newSpectator);

			t_newSpectator = tcpaccept(t_spectatorListener, 1);
		}

		// Prepare board info
		std::stringstream t_info;
		t_info << "Player " << t_turn << ":\r\n";
		for(int a = 0; a < boardHeight; a++)
		{
			for(int b = 0; b < boardWidth; b++) 
			{
				if(t_gameBoard[b][a] != 0)
					t_info << t_gameBoard[b][a] << " ";
				else
					t_info << ". ";
			}
			t_info << "\r\n";
		}

		// Check if someone has won
		if(CheckForWin(t_gameBoard, t_turn))
		{
			for(int a = 0; a < boardHeight; a++)
			{
				for(int b = 0; b < boardWidth; b++) 
				{
					if(t_gameBoard[b][a] != 0)
						t_info << t_gameBoard[b][a] << " ";
					else
						t_info << ". ";
				}
				t_info << "\r\n";
			}
			t_info << "Player " << t_turn << " Wins!!!!!\r\n";
		}

		// Send new board info to spectators
		for(int a = 0; a < t_spectators.size(); a++)
		{
			clearbuffer(0);
			writebyte(0,0);
			writestring((char*) t_info.str().data(),0);
			sendmessage(t_spectators[a], 0, 0, 0);

			std::cout << "Message Sent to Spectator " << a << "\n";
		}

		if(CheckForWin(t_gameBoard, t_turn))
		{
			PrintBoard(t_gameBoard);
			std::cout << "Player " << t_turn << "Wins!!!!!\n";
			break;
		}

		// Advance turn to next player
		if(t_turn == 1) t_turn = 2;
		else t_turn = 1;
	}

	// Tell spectators that game is over
	for(UINT a = 0; a < t_spectators.size(); a++)
	{
		clearbuffer(0);
		writebyte(1,0);
		sendmessage(t_spectators[a], 0, 0, 0);
	}

	delete t_player1;
	delete t_player2;

	CleanUp();

	//SaveThreatReference("threatRef.txt");

	system("PAUSE");
	return 0;
}

bool CheckForWin(Board& _board, int _player)
{
	// Check Horizontal
	for(int a = 0; a < 19; a++)
	{
		for(int b = 0; b < 14; b++)
		{
			int t_numberInRow = 0;
			for(int c = 0; c < 5; c++)
			{
				if(_board[b + c][a] == _player) t_numberInRow++;
			}
			if(t_numberInRow == 5) return true;
		}
	}

	// Check Vertical
	for(int a = 0; a < 19; a++)
	{
		for(int b = 0; b < 14; b++)
		{
			int t_numberInColumn = 0;
			for(int c = 0; c < 5; c++)
			{
				if(_board[a][b + c] == _player) t_numberInColumn++;
			}
			if(t_numberInColumn == 5) return true;
		}
	}

	// Check Diagonal
		// Top -> Bottom Diagonals
	for(int a = 0; a < 15; a++)
	{
		for(int b = 0; b < 15; b++)
		{
			int t_numberInDiagonal = 0;
			for(int c = 0; c < 5; c++)
			{
				if(_board[a + c][b + c] == _player) t_numberInDiagonal++;
			}
			if(t_numberInDiagonal == 5) return true;
		}
	}
	// Bottom -> Top Diagonals
	for(int a = 0; a < 15; a++)
	{
		for(int b = 18; b > 3; b--)
		{
			int t_numberInDiagonal = 0;
			for(int c = 0; c < 5; c++)
			{
				if(_board[a + c][b - c] == _player) t_numberInDiagonal++;
			}
			if(t_numberInDiagonal == 5) return true;
		}
	}

	return false;
}

void PrintBoard(Board& _board)
{
	for(int a = 0; a < boardHeight; a++)
	{
		std::cout << a << " ";
		if(a <= 9) std::cout << " ";
		for(int b = 0; b < boardWidth; b++) {
			if(_board[b][a] != 0)
				std::cout << _board[b][a] << " ";
			else
				std::cout << ". ";
		}
		std::cout << "\n";
	}
	std::cout	<< "   0 1 2 3 4 5 6 7 8 9 10  12  14  16  18\n" 
				<< "                         11  13  15  17\n\n";
}